package com.sinosoft.sinopay.apiservice.allinpay.service;

import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;

import org.springframework.stereotype.Service;

import com.allinpay.XmlTools;
import com.sinosoft.sinocloud.platform.base.SinoBaseException;
import com.sinosoft.sinocloud.platform.base.SinoBaseService;
import com.sinosoft.sinocloud.platform.common.exception.biz.SinoBizException;
import com.sinosoft.sinocloud.platform.common.exception.system.SinoSystemException;
import com.sinosoft.sinocloud.platform.common.util.XStreamComponent;
import com.sinosoft.sinopay.api.common.dto.pay.PayInfoReturnDTO;
import com.sinosoft.sinopay.api.pay.dto.InterPayRequestDTO;
import com.sinosoft.sinopay.api.pay.service.InterPayApiService;
import com.sinosoft.sinopay.apiservice.allinpay.dto.CommRealtimeCollectReq;
import com.sinosoft.sinopay.apiservice.allinpay.dto.CommRealtimeCollectReqHead;
import com.sinosoft.sinopay.apiservice.allinpay.dto.CommRealtimeCollectReqXml;
import com.sinosoft.sinopay.apiservice.allinpay.dto.CommRealtimeCollectRespHead;
import com.sinosoft.sinopay.apiservice.allinpay.dto.CommRealtimePaymentResp;
import com.sinosoft.sinopay.apiservice.allinpay.dto.CommRealtimePaymentRespXml;
import com.sinosoft.sinopay.apiservice.allinpay.util.AmountTransUtil;
import com.sinosoft.sinopay.apiservice.allinpay.util.PropertiesUtils;

/**  
 * 【通联单笔实时代付 实现】
 * @author dengcanyang
 * @date 2016年12月28日 下午6:56:38 
 * @version V1.0    
 */
@Service("InterPayByRealtimePay")
public class CommRealtimePaymentServiceImpl extends SinoBaseService implements InterPayApiService{

	@Override
	public PayInfoReturnDTO payRequest(InterPayRequestDTO interPayRequestDTO)
			throws SinoBaseException, SinoSystemException {
		//定义返回信息
		PayInfoReturnDTO payInfoReturn = new PayInfoReturnDTO();  //失败 返回信息 
		try{
			AmountTransUtil amountTransUtil = new AmountTransUtil();
            String Amount = amountTransUtil.transAmount(interPayRequestDTO.getAmount());
			CommRealtimeCollectReqXml  requestXml = new  CommRealtimeCollectReqXml();
            CommRealtimeCollectReqHead reqHeadInfo = new CommRealtimeCollectReqHead();
			String tPath = "/config/allinpayConfig.properties";
			Properties properties = PropertiesUtils.readProperties(tPath);
			reqHeadInfo.setDATA_TYPE(properties.getProperty("DATA_TYPE")); // 报文头
			reqHeadInfo.setLEVEL(properties.getProperty("LEVEL")); // 处理级别
			Date date = new Date();
			SimpleDateFormat df = new SimpleDateFormat("yyyyMMddhhmmss");
			String dateNow = df.format(date);
			reqHeadInfo.setREQ_SN(properties.getProperty("REQ_SN") + dateNow); // 交易流水号 商户ID+系统时间
			reqHeadInfo.setTRX_CODE("100014"); // properties.getProperty("TRX_CODE")								
			reqHeadInfo.setMERCHANT_ID(properties.getProperty("MERCHANT_ID"));
			reqHeadInfo.setUSER_NAME(properties.getProperty("USER_NAME")); // 用户名
			reqHeadInfo.setUSER_PASS(properties.getProperty("USER_PASS")); // 用户密码
			reqHeadInfo.setVERSION(properties.getProperty("VERSION")); // 版本
			reqHeadInfo.setSIGNED_MSG(""); // 签名信息
			requestXml.setINFO(reqHeadInfo);
            CommRealtimeCollectReq reqTransSum = new CommRealtimeCollectReq(); //报文体
            reqTransSum.setBUSINESS_CODE("00600"); 
            reqTransSum.setMERCHANT_ID(properties.getProperty("MERCHANT_ID"));
            reqTransSum.setSUBMIT_TIME(interPayRequestDTO.getSubmitTime());
            reqTransSum.setBANK_CODE(interPayRequestDTO.getBankCode());
            reqTransSum.setACCOUNT_TYPE(properties.getProperty("ACCOUNT_TYPE"));
            reqTransSum.setACCOUNT_NO(interPayRequestDTO.getAccountNo());
            reqTransSum.setACCOUNT_NAME(interPayRequestDTO.getAccountName());
            reqTransSum.setACCOUNT_PROP(properties.getProperty("ACCOUNT_PROP"));
            reqTransSum.setAMOUNT(Amount);
            reqTransSum.setCURRENCY(properties.getProperty("CURRENCY"));
            requestXml.setTRANS(reqTransSum);
            //封装请求的xml
            XStreamComponent xstream = new XStreamComponent();
            xstream.processAnnotations(new Class[] { CommRealtimeCollectReqXml.class,CommRealtimeCollectReqHead.class,CommRealtimeCollectReq.class,		                                 
                    CommRealtimePaymentRespXml.class,CommRealtimeCollectRespHead.class,CommRealtimePaymentResp.class});
            String reqXml = properties.getProperty("Package_Header")+xstream.toXML(requestXml).replace("__", "_");
            System.out.println("请求报文：\n"+reqXml); 
            String signData = this.signMsg(reqXml);   //数据签名 部分 不是很懂
            String url = properties.getProperty("SERVER_URL");
            boolean flag =false; 
            String strResp = sendXml(signData,url,flag);
            //解析返回报文
            CommRealtimePaymentRespXml response = (CommRealtimePaymentRespXml) xstream.fromXML(strResp);
            String returnCode = response.getINFO().getRET_CODE();
            if(returnCode!=null && !returnCode.equals("0000")){
            	payInfoReturn.setReturnCode(returnCode);
                payInfoReturn.setReturnMsg(response.getINFO().getERR_MSG());
            }else{  //成功 返回信息
                if(response.getTRANSRET().getRET_CODE().equals("0000")){
                    payInfoReturn.setReturnCode(response.getTRANSRET().getRET_CODE());  //返回编码 
                    payInfoReturn.setReturnMsg(response.getTRANSRET().getERR_MSG());
                    payInfoReturn.setPayAmount(interPayRequestDTO.getAmount());
                }else{
                    payInfoReturn.setReturnCode(response.getTRANSRET().getRET_CODE());
                    payInfoReturn.setReturnMsg(response.getTRANSRET().getERR_MSG());
                    }  
	            }
            }catch(Exception ex){
            	ex.printStackTrace();
				payInfoReturn.setReturnCode("FAIL");
				payInfoReturn.setReturnMsg(ex.getMessage());
		}
		return payInfoReturn;
	}
	//响应 报文信息
	public String sendXml(String xml,String url,boolean isFront) throws UnsupportedEncodingException, Exception{
		String resp="";
		try {
			resp=XmlTools.send(url,new String(xml.getBytes(),"UTF-8"));
		} catch (SinoBaseException ee) {
            throw new SinoBizException(ee.getMessage());
        }catch (Exception e) {
            //e.printStackTrace();
            throw new SinoBizException("请求发送异常："+e.getMessage());
        }
		String rootPath = this.getClass().getResource("").getPath().toString();
        String pathPfx = rootPath + "config/allinpay-pds.cer";
		/*File directory = new File("");
        String pathPfx = "\\"+directory.getAbsolutePath()+"\\resources\\config\\allinpay-pds.cer";*/
        boolean flag= false;
        try {
        	flag= this.verifyMsg(resp, pathPfx,isFront);  //暂时不做签验
		} catch (Exception e) { 
			e.printStackTrace();
			throw new SinoBizException("返回报文秘钥签验异常："+e.getMessage());
		}
		if(flag){
			System.out.println("响应内容验证通过") ;
		}else{
			System.out.println("响应内容验证不通过") ;
		}
		return resp;
	}
	/**
	 * 验证签名
	 * @param msg
	 * @return
	 *日期：Sep 9, 2012
	 * @throws Exception 
	 */
	public boolean verifyMsg(String msg,String cer,boolean isFront) throws Exception{
	    boolean flag=XmlTools.verifySign(msg, cer, false,isFront);
		System.out.println("验签结果["+flag+"]") ;
		return flag;
	}
	/**
	 * 数据签名
	 * @param strData
	 * @return
	 * @throws CryptException
	 */
	public String signMsg(String strData) throws Exception {
        System.out.println("-----star---获取数据签名-------");
        String rootPath = this.getClass().getResource("").getPath().toString();
        String pathPfx = rootPath + "config/20060400000044502.p12";
        //获取resource 文件夹签名信息 ，使用交易服务读取路径有问题；
        /*File directory = new File("");
        String pathPfx = "\\"+directory.getAbsolutePath()+"\\resources\\config\\20060400000044502.p12";*/
        String pass="111111";
        String xml= signRSAMsg(strData,pathPfx,pass);
        System.out.println("发送报文信息:\n"+xml);
        return  xml;
    }
	/**
	 * 报文签名 加密
	 * @param msg
	 * @return
	 * @throws Exception 
	 */
	public String signRSAMsg(String xml,String pathPfx,String pass) throws Exception{
	    try {
	        xml=XmlTools.signMsg(xml, pathPfx,pass, false);
        } catch (Exception e) {
            throw new SinoBizException("请求报文秘钥签验异常："+e.getMessage());
        }
		return xml;
	}
}
